﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace System
{
    /// <summary>
    /// 提供一些枚举的通用方法
    /// </summary>
    /// <creator>marc</creator>
    public static class EnumUtils
    {
        /// <summary>
        /// 将枚举<see langword="enum"/>转化为字典结构
        /// </summary>
        /// <typeparam name="TEnumType">表示枚举类型</typeparam>
        /// <typeparam name="TValueType">表示枚举值类型</typeparam>
        /// <returns>返回该枚举的字典结构，key为该枚举值对应的字符串，value为枚举值</returns>
        public static IDictionary<string, TValueType> ToDictionary<TEnumType, TValueType>() where TEnumType : Enum
        {
            Dictionary<string, TValueType> dic = new Dictionary<string, TValueType>();
            Array values = Enum.GetValues(typeof(TEnumType));
            foreach (var value in values)
            {
                dic.Add(value.ToString(), (TValueType)value);
            }

            return dic;
        }

        /// <summary>
        /// 将枚举<see langword="enum"/>转化为字典结构
        /// </summary>
        /// <typeparam name="TEnumType">表示枚举类型</typeparam>
        /// <typeparam name="TValueType">表示枚举值类型</typeparam>
        /// <returns>返回该枚举的字典结构，key为该枚举值对应的字符串，value为枚举值</returns>
        public static IList<EnumScheme<TValueType>> ToList<TEnumType, TValueType>() where TEnumType : Enum
        {
            List<EnumScheme<TValueType>> list = new List<EnumScheme<TValueType>>();
            IDictionary<string, TValueType> dic = ToDictionary<TEnumType, TValueType>();
            dic.ForEach((pair) =>
            {
                list.Add(new EnumScheme<TValueType>
                {
                    Key = pair.Key,
                    Value = pair.Value
                });
            });

            return list;
        }

        /// <summary>
        /// 将枚举<see langword="enum"/>转化为字典结构
        /// </summary>
        /// <typeparam name="TValueType">表示枚举值类型</typeparam>
        /// <returns>返回该枚举的字典结构，key为该枚举值对应的字符串，value为枚举值</returns>
        public static IDictionary<string, TValueType> ToDictionary<TValueType>(Type enumType)
        {
            Dictionary<string, TValueType> dic = new Dictionary<string, TValueType>();
            Array values = Enum.GetValues(enumType);
            foreach (var value in values)
            {
                dic.Add(value.ToString(), (TValueType)value);
            }

            return dic;
        }

        /// <summary>
        /// 将枚举<see langword="enum"/>转化为字典结构
        /// </summary>
        /// <typeparam name="TValueType">表示枚举值类型</typeparam>
        /// <returns>返回该枚举的字典结构，key为该枚举值对应的字符串，value为枚举值</returns>
        public static IList<EnumScheme<TValueType>> ToList<TValueType>(Type enumType)
        {
            List<EnumScheme<TValueType>> list = new List<EnumScheme<TValueType>>();
            IDictionary<string, TValueType> dic = ToDictionary<TValueType>(enumType);
            dic.ForEach((pair) =>
            {
                list.Add(new EnumScheme<TValueType>
                {
                    Key = pair.Key,
                    Value = pair.Value
                });
            });

            return list;
        }

        /// <summary>
        /// 将枚举<see langword="enum"/>转化为带有描述的字典结构
        /// </summary>
        /// <typeparam name="TEnumType">表示枚举类型</typeparam>
        /// <typeparam name="TValueType">表示枚举值类型</typeparam>
        /// <returns>返回该枚举的字典结构，key为该枚举值对应的字符串，value为枚举值</returns>
        public static IDictionary<string, TValueType> ToDescriptionDictionary<TEnumType, TValueType>() where TEnumType : Enum
        {
            Dictionary<string, TValueType> dic = new Dictionary<string, TValueType>();
            Array values = Enum.GetValues(typeof(TEnumType));
            foreach (var value in values)
            {
                var name = value.ToString();
                FieldInfo field = value.GetType().GetField(name);
                object[] objAtt = field.GetCustomAttributes(typeof(DescriptionAttribute), false);
                if (objAtt != null && objAtt.Length > 0 && objAtt[0] is DescriptionAttribute desc)
                {
                    name = desc.Description;
                }
                dic.Add(name, (TValueType)value);
            }

            return dic;
        }

        /// <summary>
        /// 将枚举<see langword="enum"/>转化为带有描述的枚举方案列表
        /// </summary>
        /// <typeparam name="TEnumType">表示枚举类型</typeparam>
        /// <typeparam name="TValueType">表示枚举值类型</typeparam>
        /// <returns>返回该枚举的字典结构，key为该枚举值对应的字符串，value为枚举值</returns>
        public static IList<EnumScheme<TValueType>> ToDescriptionList<TEnumType, TValueType>() where TEnumType : Enum
        {
            List<EnumScheme<TValueType>> list = new List<EnumScheme<TValueType>>();
            IDictionary<string, TValueType> dic = ToDescriptionDictionary<TEnumType, TValueType>();
            dic.ForEach((pair) =>
            {
                list.Add(new EnumScheme<TValueType>
                {
                    Key = $"{pair.Value}:{pair.Key}",
                    Value = pair.Value
                });
            });

            return list;
        }

        /// <summary>
        /// 将枚举<see langword="enum"/>转化为键值对列表
        /// </summary>
        /// <typeparam name="TEnumType">表示枚举类型</typeparam>
        /// <typeparam name="TValueType">表示枚举值类型</typeparam>
        /// <returns>返回该枚举的字典结构，key为该枚举值对应的字符串，value为枚举值</returns>
        public static IList<KeyValuePair<string, TValueType>> ToKeyValuePairList<TEnumType, TValueType>() where TEnumType : Enum
        {
            List<KeyValuePair<string, TValueType>> list = new List<KeyValuePair<string, TValueType>>();
            Array values = Enum.GetValues(typeof(TEnumType));
            foreach (object item in values)
            {
                list.Add(new KeyValuePair<string, TValueType>($"{(TValueType)item}:{item}", (TValueType)item));
            }

            return list;
        }

        /// <summary>
        /// 将枚举<see langword="enum"/>转化为带有描述的键值对列表
        /// </summary>
        /// <typeparam name="TEnumType">表示枚举类型</typeparam>
        /// <typeparam name="TValueType">表示枚举值类型</typeparam>
        /// <returns>返回该枚举的字典结构，key为该枚举值对应的字符串，value为枚举值</returns>
        public static IList<KeyValuePair<string, TValueType>> ToDescriptionKeyValuePairList<TEnumType, TValueType>() where TEnumType : Enum
        {
            List<KeyValuePair<string, TValueType>> list = new List<KeyValuePair<string, TValueType>>();
            Array values = Enum.GetValues(typeof(TEnumType));
            DescriptionAttribute descriptionAttribute = default(DescriptionAttribute);
            foreach (object item in values)
            {
                string text = item.ToString();
                FieldInfo field = item.GetType().GetField(text);
                object[] customAttributes = field.GetCustomAttributes(typeof(DescriptionAttribute), inherit: false);
                int num;
                if (customAttributes != null && customAttributes.Length != 0)
                {
                    descriptionAttribute = (customAttributes[0] as DescriptionAttribute);
                    num = ((descriptionAttribute != null) ? 1 : 0);
                }
                else
                {
                    num = 0;
                }

                if (num != 0)
                {
                    text = descriptionAttribute.Description;
                }

                list.Add(new KeyValuePair<string, TValueType>($"{(TValueType)item}:{text}", (TValueType)item));
            }

            return list;
        }
    }
}
